import 'dart:math';

import 'package:flutter/material.dart';

class ClipPage extends StatelessWidget {
  const ClipPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Clip裁剪组件详解')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          _buildClipRectDemo(),
          const SizedBox(height: 16),
          _buildClipRRectDemo(),
          const SizedBox(height: 16),
          _buildClipOvalDemo(),
          const SizedBox(height: 16),
          _buildClipPathDemo(),
          const SizedBox(height: 16),
          _buildCustomClipperDemo(),
        ],
      ),
    );
  }

  Widget _buildClipRectDemo() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            //默认剪裁掉子组件布局空间之外的绘制内容（溢出部分剪裁）
            ClipRect(
              child: Container(
                width: 200,
                height: 100,
                color: Colors.blue,
                alignment: Alignment.center,
                child: const Text(
                  '矩形裁剪',
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
            const Padding(
              padding: EdgeInsets.only(top: 8),
              child: Text(
                'ClipRect: 矩形裁剪，默认使用父容器边界裁剪',
                style: TextStyle(fontSize: 12),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildClipRRectDemo() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            //将子组件剪裁为圆角矩形
            ClipRRect(
              borderRadius: BorderRadius.circular(16),
              child: Container(
                width: 200,
                height: 100,
                color: Colors.green,
                alignment: Alignment.center,
                child: const Text(
                  '圆角矩形裁剪',
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
            const Padding(
              padding: EdgeInsets.only(top: 8),
              child: Text(
                'ClipRRect: 圆角矩形裁剪，需指定borderRadius参数',
                style: TextStyle(fontSize: 12),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildClipOvalDemo() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // 子组件为正方形时剪裁成内贴圆形；为矩形时，剪裁成内贴椭圆
            ClipOval(
              child: Container(
                width: 200,
                height: 100,
                color: Colors.orange,
                alignment: Alignment.center,
                child: const Text(
                  '椭圆形裁剪',
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
            const Padding(
              padding: EdgeInsets.only(top: 8),
              child: Text(
                'ClipOval: 椭圆形裁剪，根据容器宽高比例裁剪',
                style: TextStyle(fontSize: 12),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildClipPathDemo() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            //按照自定义的路径剪裁
            ClipPath(
              clipper: TriangleClipper(),
              child: Container(
                width: 200,
                height: 100,
                color: Colors.purple,
                alignment: Alignment.center,
                child: const Text(
                  '路径裁剪',
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
            const Padding(
              padding: EdgeInsets.only(top: 8),
              child: Text(
                'ClipPath: 自定义路径裁剪，需实现CustomClipper<Path>',
                style: TextStyle(fontSize: 12),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildCustomClipperDemo() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            ClipPath(
              clipper: StarClipper(),
              child: Container(
                width: 200,
                height: 200,
                color: Colors.red,
                alignment: Alignment.center,
                child: const Text(
                  '星星形状',
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
            const Padding(
              padding: EdgeInsets.only(top: 8),
              child: Text(
                '自定义裁剪器演示：通过继承CustomClipper实现五角星形状',
                style: TextStyle(fontSize: 12),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class TriangleClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final path = Path();
    path.moveTo(size.width / 2, 0);
    path.lineTo(size.width, size.height);
    path.lineTo(0, size.height);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

class StarClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final path = Path();
    const numberOfPoints = 5;
    final radius = size.width / 2;
    final center = Offset(size.width / 2, size.height / 2);

    for (var i = 0; i < numberOfPoints * 2; i++) {
      final angle = i * (pi * 2) / (numberOfPoints * 2);
      final currentRadius = i % 2 == 0 ? radius : radius / 2;
      final x = center.dx + currentRadius * cos(angle);
      final y = center.dy + currentRadius * sin(angle);
      if (i == 0) {
        path.moveTo(x, y);
      } else {
        path.lineTo(x, y);
      }
    }
    path.close();
    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}
